#include "SeqList.h"
#include <stdio.h>
#include<stdlib.h>
#include<assert.h>

//几个接口
void SeqListInit(SL* ps)         //初始化顺序表,接收的是实参的地址,可以直接操作实参,类型是指针类型
{
	ps->a = NULL;                //指向顺序表的指针,养成将指针置为空的习惯,避免野指针
	ps->size = ps->capacity = 0; //元素个数和容量初始值为零
}


void SeqListPushFront(SL* ps, SLDataType x)                                                                         //头插
{
	SeqListCapacity(ps);      //判断是否需要扩容
	int end = ps->size - 1;   //定义end为最后一个下标
	while (end >= 0)          //用循环向后挪动元素,条件为end(最后一个下标)大于等于0
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;
	ps->size++;

}


void SeqListPopInit(SL* ps)                                                                                          //头删
{
	int begin = 0;
	int end = ps->size - 1;
	while (begin < end)
	{
		ps->a[begin] = ps->a[begin + 1];
		begin++;
	}   //自己的方法   注意不要因为"begin+1"或"begin-1"而越界即可
	assert(ps->size > 0);        //暴力方式

	//int begin = 1;
	//while (begin < ps->size)     //size是元素个数不是下标
	//{
	//	ps->a[begin - 1] = ps->a[begin];
	//	begin++;
	//}
	ps->size--;
}


void SeqListPushBack(SL* ps, SLDataType x)                                                                         //尾插
{
	SeqListCapacity(ps);             //判断是否需要扩容     因为在外面的函数已经定义了实参ps,所以这里不写&ps
	//空间没满或已经扩容完了,后面就简单了
	ps->a[ps->size] = x;      //在后面补上要插入的元素x   其实用的是数组下角标的形式arr[i]
	ps->size++;
}


void SeqListPopBack(SL* ps)                                                                                        //尾删
{
	//if(ps->size > 0)                       //判断大小是否大于0
	//{
	//  ps->a[ps->size-1] = 0;               //若大于0则将最后一个元素置为0
	//  ps->size--;                          //将大小减1
	//}   //温柔
	assert(ps->size > 0);                    //用断言判断大小是否大于0
	ps->size--;                              //若大于0直接将大小减1
}

void SeqListPrint(SL ps)                                                                                          //打印
{
	for (int i = 0; i < ps.size; ++i)
	{
		printf("%d ", ps.a[i]);
	}
	printf("\n");
}

void SeqListDestory(SL* ps)                                                                                        //销毁
{
	free(ps->a);                              //归还空间
	ps->a = NULL;
	ps->capacity = ps->size = 0;              //容量和大小置为0
}



void SeqListCapacity(SL* ps)                                                                                      //扩容
{
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;     //分为两种情况,容量为零和容量已满,为零则
		//将新容量置为4,已满则置为原容量的2倍
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));
		//定义新指针      //指针类型    //1.旧地址     2.新内存(所要开辟的内存)大小,注意是大小是字节数
		if (tmp == NULL)           //若realloc返回NULL,则扩容失败,需手动处理避免内存泄漏,
		{                          //这一步经常和上一步一起出现
			printf("realloc fail\n");
			exit(-1);
		}
		ps->a = tmp;               //若扩容成功则使用新地址
		ps->capacity = newcapacity;  //更新容量
	}
}

void SeqListFind(SL* ps, SLDataType x)                                                                            //查找
{
	int flag = 1;
	for (int i = 0; i <= ps->size; i++)
	{
		if (x == ps->a[i])
		{
			printf("在第%d个\n", i);
			flag = 0;
			break;
		}
	}
	if (flag)
		printf("没有找到\n");
}

void SeqListInsert(SL* ps, int pos, SLDataType x)                                                                 //指定位置插入
{
	

	assert(pos >= 0 && pos <= ps->size); //粗暴

	SeqListCapacity(ps);    //判断是否需要扩容
	for (int i = ps->size - 1; i >= pos; i--)
	{ 
		ps->a[i + 1] = ps->a[i];
	}
	ps->a[pos] = x;
	ps->size++;
}

void SeqListErase(SL* ps, int pos)
{
	assert(pos < 0 || pos >= ps->size);    //粗暴
	
	int begin = pos + 1;
	
	while (begin <= ps->size)
	{
		ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;
}
